import tool from "./tool"

let callBacks = []
let socket

export default {
  init(openId) {
    if (tool.store.getItem('wsConnected') !== undefined) return
    let handleKeepAlive
    let handleConnectedId = this.on('connected', (e) => {
      if (e) {
        tool.store.setItem('wsConnected', 1)
        console.log('WebSocket 已连接')

        handleKeepAlive = setInterval(() => {
          this.send('keepAlive')
        }, 20 * 1000);
      }
    })
    // app.js 或你自己的页面逻辑中
    socket = wx.connectSocket({
      url: 'wss://syg.ldazhe.cn/api'
    })

    // 监听打开
    socket.onOpen(() => {
      this.send('openId', openId)
    })

    // 监听消息
    socket.onMessage((res) => {
      let msg = res.data
      try {
        msg = JSON.parse(msg)
        callBacks.forEach(item => {
          if (item.key === msg.key) {
            (async () => {
              try {
                await item.callBack(msg.value)
              } catch (error) {

              }
            })()
          }
        })
      } catch (error) {

      }
    })

    // 监听关闭
    socket.onClose(async () => {
      console.log('WebSocket 已关闭')
      tool.store.setItem('wsConnected', undefined)
      let reconnectTime = tool.store.getItem('wsReconnectTime')
      if (reconnectTime === undefined) {
        reconnectTime = 0
      }
      reconnectTime++
      tool.store.setItem('wsReconnectTime', reconnectTime)
      if (reconnectTime === 5) {
        tool.store.setItem('wsConnected', -1)
      } else {
        await tool.wait(1)
        this.removeCallBack(handleConnectedId)
        clearInterval(handleKeepAlive)
        this.init(openId)
        setTimeout(() => {
          tool.store.removeItem('wsReconnectTime')
        }, 3000);
      }
    })

    // 监听出错
    socket.onError((err) => {
      console.error('WebSocket 错误', err)
    })
  },
  send(key, value) {
    socket.send({
      data: JSON.stringify({
        key,
        value
      })
    })
  },
  on(key, callBack) {
    let id = new Date()
    callBacks.push({
      id,
      key,
      callBack
    })
    return id
  },
  removeCallBack(id) {
    callBacks = callBacks.filter(item => item.id !== id)
  }
}